package com.wzdigit.wms.raw.service.gdn;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.request.outstock.CancelPickMaterialRequest;
import com.wzdigit.wms.basic.domain.asn.AsnDtl;
import com.wzdigit.wms.basic.domain.asn.AsnDtlGoods;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.domain.dtos.api.ApiMessage;
import com.wzdigit.wms.basic.domain.dtos.api.ApiSapMessage;
import com.wzdigit.wms.basic.domain.transfer.GdnDtl;
import com.wzdigit.wms.basic.domain.transfer.GdnDtlGoods;
import com.wzdigit.wms.basic.domain.transfer.GdnHeader;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.mapper.core.order.AsnDtlGoodsMapper;
import com.wzdigit.wms.basic.mapper.core.order.AsnDtlMapper;
import com.wzdigit.wms.basic.mapper.core.order.AsnHeaderMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.GdnDtlGoodsMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.GdnDtlMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.GdnHeaderMapper;
import com.wzdigit.wms.raw.mapper.gdn.DeliveryNewMapper;
import com.wzdigit.wms.raw.service.outstock.PickMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *生产领/退料删改接口
 * Created by zyf on 2021/9/14 9:38
 */
@Service
@Slf4j
public class GdnDtlCancelService {
    private static final List<String> GDN_TPE_LIST= Arrays.asList(GdnTypeEnum.D02.code,GdnTypeEnum.D21.code,GdnTypeEnum.D28.code);
    private static final  List<Integer> dtlStatusList= Arrays.asList(GdnDtlStatusEnum.CANCEL.code,
            GdnDtlStatusEnum.SHIPMENTED.code,GdnDtlStatusEnum.CLOSE.code);
    private static final  List<Integer> CANCEL_DTL= Arrays.asList(GdnDtlStatusEnum.CANCEL.code);

    @Autowired
    private GdnHeaderMapper gdnHeaderMapper;
    @Autowired
    private GdnDtlMapper gdnDtlMapper;
    @Autowired
    private DeliveryNewMapper deliveryMapper;
    @Autowired
    private AsnHeaderMapper asnHeaderMapper;
    @Autowired
    private AsnDtlMapper asnDtlMapper;
    @Autowired
    private AsnDtlGoodsMapper asnDtlGoodsMapper;

/*
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ApiSapMessage cancelDtlGdnOld(String gdnNo, String  sourceShipItem, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{
        GdnHeader gdnHeader = gdnHeaderMapper.selectOne(new QueryWrapper<GdnHeader>().eq("GDN_NO", gdnNo));
        if (gdnHeader==null){
            return  new ApiSapMessage(ApiSapMessage.STATUS_ONWAY,"查无对应出库单!");
        }
        if (!GDN_TPE_LIST.contains(gdnHeader.getGdnType())){
            return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该发货单非生产领料单!");
        }

        Boolean falg=true;//为false表示发货单为一次过账，且状态为已完成，可以让sap关单

        if (gdnHeader.getStatus()==GdnHeaderStatusEnum.FINISH.code){
            switch (gdnHeader.getGdnType()){
                case "D21": //易损件领料单 一次过账
                    falg=false;
                    break;
                case "D28" : //生产领料(单次) 一次过账
                    falg=false;
                    break;
            }
            //如果回传失败，不允许关单
            Integer failCount = deliveryMapper.selectFailGdn(gdnNo);
            if (failCount>0){
                falg=true;
            }
        }

        if (falg){
            if (gdnHeader.getStatus()==GdnHeaderStatusEnum.FINISH.code){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该发货单已经完成");
            }
            GdnDtl gdnDtl = gdnDtlMapper.selectOne(new QueryWrapper<GdnDtl>().eq("GDN_HEADER_ID", gdnHeader.getGdnHeaderId()).eq("GDN_REF5", sourceShipItem));


            if (gdnDtl==null){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"查无对应出库单明细!");
            }
            if ((gdnDtl.getShipQty().compareTo(gdnDtl.getPickQty()))!=0){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"拣料数大于出库数,请取消拣料!");
            }
            Date nowDate=new Date();
            BigDecimal headerId = new BigDecimal(gdnHeader.getGdnHeaderId());
            //先更新明细状态，防止取消过程中拣料/出库了
            if (gdnDtl.getShipQty().compareTo(BigDecimal.ZERO)==1){
                deliveryMapper.updateGdnDtl(new BigDecimal(gdnDtl.getGdnDtlId()), GdnDtlStatusEnum.SHIPMENTED.code,
                        "system",nowDate,BigDecimal.ZERO,nowDate);
            }else {
                deliveryMapper.updateGdnDtl(new BigDecimal(gdnDtl.getGdnDtlId()), GdnDtlStatusEnum.CANCEL.code,
                        "system",nowDate,BigDecimal.ZERO,nowDate);
            }


            Integer allCount = deliveryMapper.selectCountDtl(headerId, null);
            //查询明细状态为取消，发运，关闭的条数
            Integer deliveryCount = deliveryMapper.selectCountDtl(headerId, dtlStatusList);
            //查询明细为取消的条数
            Integer cancelCount = deliveryMapper.selectCountDtl(headerId, CANCEL_DTL);
            if (allCount.equals(deliveryCount)){
                log.info("更新出库单主档状态---"+gdnNo);
                deliveryMapper.updateGdnHeader(gdnNo, GdnHeaderStatusEnum.FINISH.code,"system",nowDate,nowDate);
            }
            if (allCount.equals(cancelCount)){
                log.info("更新出库单主档状态---"+gdnNo);
                deliveryMapper.updateGdnHeader(gdnNo, GdnHeaderStatusEnum.CANCEL.code,"system",nowDate,nowDate);
            }
        }
        return  new ApiSapMessage(ApiSapMessage.STATUS_OK,"取消成功");
    }
*/

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ApiSapMessage cancelDtlGdn(String gdnNo, String  sourceShipItem,String type, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{
        log.info(gdnNo+"/"+sourceShipItem+"SAP取消关单开始");
        log.info("取消类型"+type);
        if ("1".equals(type)){
            GdnHeader gdnHeader = gdnHeaderMapper.selectOne(new QueryWrapper<GdnHeader>().eq("GDN_NO", gdnNo));
            if (gdnHeader==null){
                return  new ApiSapMessage(ApiSapMessage.STATUS_ONWAY,"查无对应出库单!");
            }
            if (!GDN_TPE_LIST.contains(gdnHeader.getGdnType())){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该发货单非生产领料单!");
            }

            Boolean falg=true;//为false表示发货单为一次过账，且状态为已完成，可以让sap关单

            if (gdnHeader.getStatus()==GdnHeaderStatusEnum.FINISH.code){
                switch (gdnHeader.getGdnType()){
                    case "D21": //易损件领料单 一次过账
                        falg=false;
                        break;
                    case "D28" : //生产领料(单次) 一次过账
                        falg=false;
                        break;
                }
                //如果回传失败，不允许关单
                Integer failCount = deliveryMapper.selectFailGdn(gdnNo);
                if (failCount>0){
                    falg=true;
                }
            }

            if (falg) {
                if (gdnHeader.getStatus() == GdnHeaderStatusEnum.FINISH.code) {
                    return new ApiSapMessage(ApiSapMessage.STATUS_NO, "该发货单已经完成");
                }
            }
                GdnDtl gdnDtl = gdnDtlMapper.selectOne(new QueryWrapper<GdnDtl>().eq("GDN_HEADER_ID", gdnHeader.getGdnHeaderId()).eq("GDN_REF5", sourceShipItem));


                if (gdnDtl==null){
                    return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"查无对应出库单明细!");
                }
                if ((gdnDtl.getShipQty().compareTo(gdnDtl.getPickQty()))!=0){
                    return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"拣料数大于出库数,请取消拣料!");
                }
                Date nowDate=new Date();
                BigDecimal headerId = new BigDecimal(gdnHeader.getGdnHeaderId());
                //先更新明细状态，防止取消过程中拣料/出库了
                if (gdnDtl.getShipQty().compareTo(BigDecimal.ZERO)==1){
                    deliveryMapper.updateGdnDtl(new BigDecimal(gdnDtl.getGdnDtlId()), GdnDtlStatusEnum.SHIPMENTED.code,
                            "system",nowDate,BigDecimal.ZERO,nowDate);
                }else {
                    deliveryMapper.updateGdnDtl(new BigDecimal(gdnDtl.getGdnDtlId()), GdnDtlStatusEnum.CANCEL.code,
                            "system",nowDate,BigDecimal.ZERO,nowDate);
                }


                Integer allCount = deliveryMapper.selectCountDtl(headerId, null);
                //查询明细状态为取消，发运，关闭的条数
                Integer deliveryCount = deliveryMapper.selectCountDtl(headerId, dtlStatusList);
                //查询明细为取消的条数
                Integer cancelCount = deliveryMapper.selectCountDtl(headerId, CANCEL_DTL);
                if (allCount.equals(deliveryCount)){
                    log.info("更新出库单主档状态---"+gdnNo);
                    deliveryMapper.updateGdnHeader(gdnNo, GdnHeaderStatusEnum.FINISH.code,"system",nowDate,nowDate);
                }
                if (allCount.equals(cancelCount)){
                    log.info("更新出库单主档状态---"+gdnNo);
                    deliveryMapper.updateGdnHeader(gdnNo, GdnHeaderStatusEnum.CANCEL.code,"system",nowDate,nowDate);
                }

        }else if ("2".equals(type)){
            AsnHeader asnHeader = asnHeaderMapper.selectOne(new QueryWrapper<AsnHeader>().eq("ASN_NO", gdnNo));
            if (asnHeader==null){
                return  new ApiSapMessage(ApiSapMessage.STATUS_ONWAY,"查无对应领料单!");
            }
            if (!asnHeader.getAsnType().equals(AsnTypeEnum.R11.code)){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该发货单非生产领料单!");
            }
            if (asnHeader.getStatus().equals(AsnHeaderStatusEnum.FINISH.code)){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该领料单已经完成");
            }
            AsnDtl asnDtl = asnDtlMapper.selectOne(new QueryWrapper<AsnDtl>().
                    eq("ASN_HEADER_ID", asnHeader.getAsnHeaderId()).
                    eq("ASN_REF5", sourceShipItem));
            if (asnDtl==null){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"查无对应领料单明细!");
            }
            if (!asnDtl.getStatus().equals(AsnDtlStatusEnum.CREATE.code)){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该领料单明细已作业!");
            }
            List<AsnDtlGoods> asnDtlGoods = asnDtlGoodsMapper.selectList(new QueryWrapper<AsnDtlGoods>().eq("ASN_DTL_ID", asnDtl.getAsnDtlId()));
            if (asnDtlGoods!=null&&asnDtlGoods.size()>0){
                return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"该领料单明细已作业!");
            }
            //更新生产领料单
            log.info("生产领料单取消---"+gdnNo);
            AsnDtl asnDtlUpdate=new AsnDtl();
            asnDtlUpdate.setAsnDtlId(asnDtl.getAsnDtlId());
            asnDtlUpdate.setModifyTime(new Date());
            asnDtlUpdate.setModifyUser("system");
            asnDtlUpdate.setStatus(AsnDtlStatusEnum.CANCEL.code);
            asnDtlMapper.updateById(asnDtlUpdate);

            //查询收料单所有明细
            List<AsnDtl> chenckDtlList = asnDtlMapper.selectList(new QueryWrapper<AsnDtl>().eq("ASN_HEADER_ID", asnHeader.getAsnHeaderId()));
            int allSize = chenckDtlList.size();
            int checkSize=0;
            int cancelSize=0;
            for (AsnDtl dtl : chenckDtlList) {
                if (dtl.getStatus().equals(AsnDtlStatusEnum.FINISH.code)||dtl.getStatus().equals(AsnDtlStatusEnum.CANCEL.code)){
                    checkSize++;
                }
                if (dtl.getStatus().equals(AsnDtlStatusEnum.CANCEL.code)){
                    cancelSize++;
                }
            }
            if (checkSize==allSize){
                log.info("更新出库单主档状态---"+gdnNo);
                int asnHeaderStatus = AsnHeaderStatusEnum.FINISH.code;
                if (cancelSize==allSize){
                    asnHeaderStatus = AsnHeaderStatusEnum.CANCEL.code;
                }
                AsnHeader asnHeaderUpdate=new AsnHeader();
                asnHeaderUpdate.setAsnHeaderId(asnHeader.getAsnHeaderId());
                asnHeaderUpdate.setModifyUser("system");
                asnHeaderUpdate.setModifyTime(new Date());
                asnHeaderUpdate.setStatus(asnHeaderStatus);
                asnHeaderMapper.updateById(asnHeaderUpdate);
            }

        }else {
            return  new ApiSapMessage(ApiSapMessage.STATUS_NO,"参数类型错误!");
        }

        return  new ApiSapMessage(ApiSapMessage.STATUS_OK,"取消成功");
    }

}
